package com.platform.modular.util;

import com.platform.common.utils.JsonUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

/**
 * @author yifei.han
 * @version 1.0
 * @className HttpClientUtil
 * @description
 * @date 2020/12/10
 */
@Component
public class HttpClientUtil {

    private static Logger LOGGER = LoggerFactory.getLogger(HttpClientUtil.class);

    /**
     * HttpPost 请求
     * @param requestUrl   请求地址
     * @param requestJson  json数据
     * @param headerMap  header数据
     * @return
     */
    public String httpJsonPost(String requestUrl, String requestJson, Map<String, String> headerMap,
                               Integer source, Long businessId)  {
        String strResult = "";
        CloseableHttpClient httpClient = null;
        HttpEntity resEntity;
        CloseableHttpResponse response = null;
        try {
            LOGGER.info("请求地址：{}", requestUrl);
            LOGGER.info("请求参数：{}", requestJson);
            StringEntity myEntity = new StringEntity(requestJson, "UTF-8");
            HttpPost httpPost = new HttpPost(requestUrl);
            httpClient = getHttpClient();
            Iterator<Map.Entry<String, String>> iterator = headerMap.entrySet().iterator();
            while (iterator.hasNext()) {
                Map.Entry<String, String> next = iterator.next();
                httpPost.addHeader(next.getKey(), next.getValue());
            }
            httpPost.setEntity(myEntity);
            response = httpClient.execute(httpPost);
            resEntity = response.getEntity();
            int statusCode = response.getStatusLine().getStatusCode();
            LOGGER.info("http请求状态码：" + statusCode);
            if (statusCode == 200 && resEntity != null) {
                strResult = EntityUtils.toString(resEntity, "UTF-8");
            }
        } catch (Exception e) {
            LOGGER.error(e.getMessage() , e);
        } finally {
            LOGGER.info("响应信息：{}", strResult);
            closeResourse(response, httpClient);
        }
        return strResult;
    }


    public byte[] httpJsonPostToByte(String requestUrl, String requestJson, Map<String, String> headerMap)  {
        CloseableHttpClient httpClient = null;
        HttpEntity httpEntity = null;
        CloseableHttpResponse response = null;
        byte[] byteArray = null;
        try {
            LOGGER.info("请求地址：{}", requestUrl);
            LOGGER.info("请求参数：{}", requestJson);
            StringEntity myEntity = new StringEntity(requestJson, "UTF-8");
            HttpPost httpPost = new HttpPost(requestUrl);
            httpClient = getHttpClient();
            Iterator<Map.Entry<String, String>> iterator = headerMap.entrySet().iterator();
            while (iterator.hasNext()) {
                Map.Entry<String, String> next = iterator.next();
                httpPost.addHeader(next.getKey(), next.getValue());
            }
            httpPost.setEntity(myEntity);
            response = httpClient.execute(httpPost);
            httpEntity = response.getEntity();
            int statusCode = response.getStatusLine().getStatusCode();
            LOGGER.info("http请求状态码：" + statusCode);
            if (statusCode == 200 && httpEntity != null) {
                try {
                    byteArray = EntityUtils.toByteArray(httpEntity);
                } catch (IOException e) {
                    try {
                        String qrCodeResult = EntityUtils.toString(httpEntity, "UTF-8");
                        LOGGER.info("qrCodeResult：{}", qrCodeResult);
                    } catch (IOException e1) {
                        LOGGER.info(e.getMessage(), e);
                        LOGGER.info("获取响应数据失败");
                    }
                }
            }
        } catch (Exception e) {
            LOGGER.error(e.getMessage() , e);
        } finally {
            closeResourse(response, httpClient);
        }
        return byteArray;
    }

    /**
     * HttpPost 请求
     * @param requestUrl 请求地址
     * @param requestParams  请求参数
     * @return
     */
    public static String httpFormPost(String requestUrl, Map<String, Object> requestParams) {
        // 获取连接客户端工具
        String entityStr = null;
        CloseableHttpClient httpClient = null;
        CloseableHttpResponse response = null;
        try {
            // 创建POST请求对象
            HttpPost httpPost = new HttpPost(requestUrl);
            List<NameValuePair> requstParamList = new LinkedList<>();
            LOGGER.info("请求地址：{}", requestUrl);
            LOGGER.info("请求参数：{}", JsonUtils.objectToJson(requestParams));
            if (requestParams != null && !requestParams.isEmpty()) {
                Iterator it = requestParams.entrySet().iterator();
                while (it.hasNext()) {
                    Map.Entry entry = (Map.Entry) it.next();
                    Object key = entry.getKey();
                    Object value = entry.getValue();
//                    LOGGER.info("请求参数---" + key.toString() + "--" + value.toString());
                    requstParamList.add(new BasicNameValuePair(key.toString(), value.toString()));
                }
            }
            // 使用URL实体转换工具
            UrlEncodedFormEntity entityParam = new UrlEncodedFormEntity(requstParamList, "UTF-8");
            httpPost.setEntity(entityParam);
            httpClient = getHttpClient();
            response = httpClient.execute(httpPost);
            int statusCode = response.getStatusLine().getStatusCode();
            if (statusCode == HttpStatus.SC_OK) {
                HttpEntity entity = response.getEntity();
                entityStr = EntityUtils.toString(entity, "UTF-8");
                LOGGER.info("响应结果：{}", entityStr);
            } else {
                LOGGER.info("请求状态码为：{}", statusCode);
            }
        } catch (Exception e) {
            LOGGER.info(e.getMessage(), e);
        } finally {
            // 释放连接
            closeResourse(response, httpClient);
        }
        return entityStr;
    }



    public String httpGet(String httpurl) {
        HttpURLConnection connection = null;
        InputStream is = null;
        BufferedReader br = null;
        String result = null;// 返回结果字符串
        try {
            // 创建远程url连接对象
            URL url = new URL(httpurl);
            // 通过远程url连接对象打开一个连接，强转成httpURLConnection类
            connection = (HttpURLConnection) url.openConnection();
            // 设置连接方式：get
            connection.setRequestMethod("GET");
            // 设置连接主机服务器的超时时间：15000毫秒
            connection.setConnectTimeout(15000);
            // 设置读取远程返回的数据时间：60000毫秒
            connection.setReadTimeout(60000);
            // 发送请求
            connection.connect();
            // 通过connection连接，获取输入流
            if (connection.getResponseCode() == 200) {
                is = connection.getInputStream();
                // 封装输入流is，并指定字符集
                br = new BufferedReader(new InputStreamReader(is, "UTF-8"));
                // 存放数据
                StringBuffer sbf = new StringBuffer();
                String temp = null;
                while ((temp = br.readLine()) != null) {
                    sbf.append(temp);
                    sbf.append("\r\n");
                }
                result = sbf.toString();
            }
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 关闭资源
            if (null != br) {
                try {
                    br.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            if (null != is) {
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            connection.disconnect();// 关闭远程连接
        }
        return result;
    }

    private static void closeResourse(CloseableHttpResponse response, CloseableHttpClient httpclient) {
        if (response != null) {
            try {
                response.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        if (httpclient != null) {
            try {
                httpclient.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }


    private static CloseableHttpClient getHttpClient() {
        RequestConfig requestConfig = null;
        CredentialsProvider credsProvider = new BasicCredentialsProvider();
//        if ("1".equals(PROXY_SWITCH)) {
//            int port = Integer.parseInt(PROXY_PORT);
//            HttpHost proxy = new HttpHost(PROXY_IP, port);
//            requestConfig = RequestConfig.custom().setProxy(proxy).setConnectTimeout(120000)
//                    .setConnectionRequestTimeout(120000).setSocketTimeout(120000).build();
//        } else {
            requestConfig = RequestConfig.custom().setConnectTimeout(120000)
                    .setConnectionRequestTimeout(120000).setSocketTimeout(120000).build();
//        }
        return HttpClients.custom().setDefaultCredentialsProvider(credsProvider)
                .setDefaultRequestConfig(requestConfig).build();
    }

}
